package com.myzl.coal.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.myzl.coal.domain.Device;
import com.myzl.coal.domain.RealTimeData;
import com.myzl.coal.mongo.component.MongoComponent;
import com.myzl.coal.mongo.domain.HistoryData;
import com.myzl.coal.python.PythonInvokeUtils;
import com.myzl.coal.service.IDeviceService;
import com.myzl.coal.service.IPythonService;
import com.myzl.coal.service.IRealTimeDataService;
import com.myzl.common.config.ImageRecognitionConfig;
import com.myzl.common.enums.PictureRecognitionEnum;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 设备表Service业务层处理
 *
 * @author myzl
 * @date 2022-09-01
 */
@Service
@Data
@Slf4j(topic = "admin-user")
public class PythonServiceImpl implements IPythonService {

    private final IRealTimeDataService realtimeDataService;
    private final MongoComponent mongoComponent;
    private final IDeviceService deviceService;
    private final ImageRecognitionConfig imageRecognitionConfig;

    @Override
    public List<JSONObject> imageTest(List<String> paths) {
        List<String> spitPath = invokeSpit(paths);
        List<JSONObject> res = spitPath.stream().map(e -> {
            List<String> predictionResults = invokePythonPrediction(e);
            JSONObject jsonObject = new JSONObject();
            if (!CollectionUtils.isEmpty(predictionResults)) {
//                AnalysisResults:{'lump coal': 2, 'slack': 4, 'sieve': 1, 'other': 3}
                String predictionResult = predictionResults.get(predictionResults.size() - 1);
                String result = StrUtil.removePrefix(predictionResult, "AnalysisResults:");
                jsonObject = JSON.parseObject(result);
            }
            return jsonObject;
        }).collect(Collectors.toList());

        return res;
    }

    @Override
    public String imageCorrect(String inputPath, String points, String height, String outputPath) {
        List<String> results = PythonInvokeUtils.invokeRelativeUrl("handle.py",
                "-i", inputPath,
                "-s", points,
                "-x", height,
                "-o", outputPath
        );
        boolean flag = false;
        for (String s : results) {
            if (s.contains("Successfully")) {
                flag = true;
            }
        }
        return flag ? outputPath : "";
    }

    @Override
    public List<String> invokeSpit(List<String> paths) {
        List<String> list = PythonInvokeUtils.invokeRelativeUrl("spit.py", StrUtil.join(",", paths));
        return list.stream().skip(2).collect(Collectors.toList());
    }

    @Override
    public List<String> invokePythonPrediction(String inferImgs) {
        List<String> result = PythonInvokeUtils.invokePython(imageRecognitionConfig.getPredict_cls_path(),
                "-c",
                imageRecognitionConfig.getModel_path(),
                "-o"
                , "Global.infer_imgs='" + inferImgs + "'"
        );
        return result;
    }

    @Override
    public void invokePrediction(List<String> paths) {
        List<String> spitPath = invokeSpit(paths);

        spitPath.forEach(e->{
            List<String> predictionResults = invokePythonPrediction(e);
            if(!CollectionUtils.isEmpty(predictionResults)){
//                AnalysisResults:{'lump coal': 2, 'slack': 4, 'sieve': 1, 'other': 3}
                String predictionResult = predictionResults.get(predictionResults.size() - 1);
                String result = StrUtil.removePrefix(predictionResult, "AnalysisResults:");
                JSONObject jsonObject = JSON.parseObject(result);
                Integer lump_coal = jsonObject.getInteger(PictureRecognitionEnum.LUMP_COAL.getSign());
                Integer slack = jsonObject.getInteger(PictureRecognitionEnum.SLACK.getSign());
                Integer sieve = jsonObject.getInteger(PictureRecognitionEnum.SIEVE.getSign());
                Integer other = jsonObject.getInteger(PictureRecognitionEnum.OTHER.getSign());
                String[] split = e.split("/");

                String name = split[split.length - 1];
                log.info("========================:"+split[split.length - 1]);
                if(split.length>0){
                    String[] s = name.split("_");
                    Date pictureDate = DateUtil.parse(s[0], DatePattern.PURE_DATETIME_MS_PATTERN);
                    Integer deviceId=Integer.parseInt(s[1]);

                    Device service = deviceService.getById(deviceId);

                    RealTimeData realTimeData = new RealTimeData();
                    realTimeData.setDataValue(String.valueOf(lump_coal));
                    realTimeData.setDeviceId(deviceId);
                    realTimeData.setDeviceType(service.getDeviceType());
                    realTimeData.setRemark(name);
                    realTimeData.setDictValue(PictureRecognitionEnum.LUMP_COAL.getCode());

                    RealTimeData realTimeDataSlack = new RealTimeData();
                    realTimeDataSlack.setDataValue(String.valueOf(slack));
                    realTimeDataSlack.setDeviceId(deviceId);
                    realTimeDataSlack.setDeviceType(service.getDeviceType());
                    realTimeDataSlack.setRemark(name);
                    realTimeDataSlack.setDictValue(PictureRecognitionEnum.SLACK.getCode());

                    RealTimeData realTimeDataSieve = new RealTimeData();
                    realTimeDataSieve.setDataValue(String.valueOf(sieve));
                    realTimeDataSieve.setDeviceId(deviceId);
                    realTimeDataSieve.setDeviceType(service.getDeviceType());
                    realTimeDataSieve.setRemark(name);
                    realTimeDataSieve.setDictValue(PictureRecognitionEnum.SIEVE.getCode());

                    RealTimeData realTimeDataOther = new RealTimeData();
                    realTimeDataOther.setDataValue(String.valueOf(other));
                    realTimeDataOther.setDeviceId(deviceId);
                    realTimeDataOther.setDeviceType(service.getDeviceType());
                    realTimeDataOther.setRemark(name);
                    realTimeDataOther.setDictValue(PictureRecognitionEnum.OTHER.getCode());

                    List<RealTimeData> realTimeDataList=new ArrayList<>();
                    realTimeDataList.add(realTimeData);
                    realTimeDataList.add(realTimeDataSlack);
                    realTimeDataList.add(realTimeDataSieve);
                    realTimeDataList.add(realTimeDataOther);

                    realtimeDataService.updateRealTimeDataByType(realTimeDataList);

                    List<HistoryData> mongoDataList = realTimeDataList.stream().map(data -> {
                        HistoryData mongoHistoryData = new HistoryData();
                        BeanUtils.copyProperties(data,mongoHistoryData);
                        mongoHistoryData.initBasic();
                        return mongoHistoryData;
                    }).collect(Collectors.toList());
                    mongoComponent.saveBatch(mongoDataList,"HistoryData");
                }else {
                    log.info("python解析脚本有误路径:{}",e);
                }
            }else {
                log.info("python解析脚本有误路径:{}",e);
            }
        });

    }

    public static void main(String[] args) {
//        List<String> paths = Arrays.asList("C:/Users/91941/Desktop/test/20234271445000_1.jpg", "C:/Users/91941/Desktop/test/20234271445000_2.jpg");
//        List<String> list = PythonInvokeUtils.invokeRelativeUrl("spit.py", StrUtil.join(",", paths));
//        List<String> collect = list.stream().skip(2).collect(Collectors.toList());
//        System.out.println();

        String predictionResult = "AnalysisResults:{'lump coal': 2, 'slack': 4, 'sieve': 1, 'other': 3}";

        String result = StrUtil.removePrefix(predictionResult, "AnalysisResults:");
        JSONObject jsonObject = JSON.parseObject(result);
        Integer lump_coal = jsonObject.getInteger("lump coal");
        Integer slack = jsonObject.getInteger("slack");
        Integer sieve = jsonObject.getInteger("sieve");
        Integer other = jsonObject.getInteger("other");

        String[] split = "C:/Users/91941/Desktop/test/202304271445000_1".split("/");
        if (split.length > 0) {
            String[] s = split[split.length - 1].split("_");
            Date pictureDate = DateUtil.parse(s[0], DatePattern.PURE_DATETIME_MS_PATTERN);
            Integer deviceId = Integer.parseInt(s[1]);

            RealTimeData realTimeData = new RealTimeData();
            realTimeData.setDataValue(String.valueOf(lump_coal));
            realTimeData.setDeviceId(deviceId);
            realTimeData.setCreateTime(pictureDate);
            realTimeData.setDictValue(3000);

            RealTimeData realTimeDataSlack = new RealTimeData();
            realTimeDataSlack.setDataValue(String.valueOf(slack));
            realTimeDataSlack.setDeviceId(deviceId);
            realTimeDataSlack.setCreateTime(pictureDate);
            realTimeDataSlack.setDictValue(3001);

            RealTimeData realTimeDataSieve = new RealTimeData();
            realTimeDataSieve.setDataValue(String.valueOf(sieve));
            realTimeDataSieve.setDeviceId(deviceId);
            realTimeDataSieve.setCreateTime(pictureDate);
            realTimeDataSieve.setDictValue(3002);

            RealTimeData realTimeDataOther = new RealTimeData();
            realTimeDataOther.setDataValue(String.valueOf(other));
            realTimeDataOther.setDeviceId(deviceId);
            realTimeDataOther.setCreateTime(pictureDate);
            realTimeDataOther.setDictValue(3003);

            List<RealTimeData> realTimeDataList = new ArrayList<>();
            realTimeDataList.add(realTimeData);
            realTimeDataList.add(realTimeDataSlack);
            realTimeDataList.add(realTimeDataSieve);
            realTimeDataList.add(realTimeDataOther);

//            realtimeDataService.updateRealTimeDataByType(realTimeDataList);

            List<HistoryData> mongoDataList = realTimeDataList.stream().map(data -> {
                HistoryData mongoHistoryData = new HistoryData();
                BeanUtils.copyProperties(data, mongoHistoryData);
                return mongoHistoryData;
            }).collect(Collectors.toList());
//            mongoComponent.saveOrUpdateBatch(mongoDataList,"HistoryData");
        }
    }
}
